#include "Database.h"

Database::Database(int numRows) : db(std::make_unique<Db>(numRows)) {}

void Database::executeTransactions(const std::vector<Transaction>& transactions) {
    for ( auto& transaction : transactions) {
        for (auto& operations : transaction.getOperations()) {
          // read operation
            if (operations.getOperationType() == 0) {
                this->rowReadLocks->at(operations.getRowNum()).lock();
                // add the lock acquired to the stack
                this->readLocksAcquired.push(operations.getRowNum());
                db->read(operations.getRowNum());
            // write operation
            } else {
                this->rowWriteLocks->at(operations.getRowNum()).lock();
                // add the lock acquired to the stack
                this->writeLocksAcquired.push(operations.getRowNum());
                db->write(operations.getRowNum(), operations.getValue());
            }
        }
        // unlock all locks
        while (!this->readLocksAcquired.empty()) {
            this->rowReadLocks->at(this->readLocksAcquired.top()).unlock();
            this->readLocksAcquired.pop();
        }
        while (!this->writeLocksAcquired.empty()) {
            this->rowWriteLocks->at(this->writeLocksAcquired.top()).unlock();
            this->writeLocksAcquired.pop();
        }
    }


}

void Database::run(const std::vector<Transaction>& transactions) {
    executeTransactions(transactions);
}